package panel;


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.geom.Line2D;

import javax.swing.JPanel;
import java.util.Vector;
import libs.Utils;



public class PanelClassificationSimulation extends JPanel {
	private static final long serialVersionUID = 1L;
    public String[] pepperNames;
    public String[] features;
    public Vector<String> v=null;
    public String type="classification"; // or it can also be a prediction 
    public boolean isOnlyPepper=false;
    public float totalNetworkConnectionWeight=0.0f;
    public float totalAbsoluteNetworkConnectionWeight=0.0f;
    private float[] trainedValues;
    private float[] desiredValues;
	private Point mousePos;
	
	public PanelClassificationSimulation(){
		super();
		if (isOnlyPepper) pepperNames=new String[53];
		init();
	}
    
	private void init() {
		this.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {   
			public void mouseMoved(java.awt.event.MouseEvent e) {    
				mousePos=e.getPoint();
				repaint();
			}
			public void mouseDragged(java.awt.event.MouseEvent e) {
				mousePos=e.getPoint();
				repaint();
			}
		});
	}

	public void paint(Graphics g){
		if (trainedValues==null || trainedValues.length==0) {
			return;
		}
		int w=this.getWidth();
		int h=this.getHeight();
		int left=30;
		int top=30;
		int bottom=h-100;
		int right=w-30;
		int height=bottom-top;
		int width=right-left;
		
		double xGap=10.0;
		int pNumber=0;
		if (isOnlyPepper) {
			pNumber=pepperNames.length;
			xGap=width*1.0/(trainedValues.length/3);
		}else{
			xGap=width*1.0/trainedValues.length;
		}
		
		Graphics2D g2d = (Graphics2D) g;
		g2d.setStroke(new BasicStroke());
		g.setColor(Color.black);
		g.fillRect(0, 0, w,h);
		g.setColor(Color.red);
		g.drawLine(left, top, left, bottom);
		g.drawLine(left, bottom, right, bottom);
	    
		if (mousePos!=null) {
			g.setColor(Color.LIGHT_GRAY);
		    g.drawLine(0,mousePos.y,this.getWidth(),mousePos.y);
		    g.drawLine(mousePos.x,0,mousePos.x,this.getHeight());
		    try {
			    int n=(int)((mousePos.x-left)/xGap);
			    int px=mousePos.x+20;
			    int py=mousePos.y+20;
			    g.setColor(Color.green);
			    if (isOnlyPepper && n>=0) {
				    g.drawString(pepperNames[n],px,py);
					setRelatedColor(g, n);
				    g.drawString("1.sample:"+trainedValues[n]+"",px,py+20);
					setRelatedColor(g, n+pNumber);
				    g.drawString("2.sample:"+trainedValues[n+pNumber]+"",px,py+40);
					setRelatedColor(g, n+2*pNumber);
				    g.drawString("3.sample:"+trainedValues[n+2*pNumber]+"",px,py+60);
				    g.setColor(Color.orange);
				    g.drawRect(px-18,py-18,150,85);
				}else{
					setRelatedColor(g, n);
				    g.drawString(trainedValues[n]+"",px,py);
				    g.setColor(Color.orange);
				    g.drawRect(px-18,py-18,150,25);
				}
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	    g.setColor(Color.green);
	    g.drawString("Total Network Connection Weight:"+totalNetworkConnectionWeight+"",20,bottom+20);
	    g.drawString("Total Absolute Network Connection Weight:"+totalAbsoluteNetworkConnectionWeight+"",20,bottom+40);
		
	    g.setColor(Color.blue);
		Stroke drawingStroke = new BasicStroke(
	    		1, 
	    		BasicStroke.CAP_BUTT, 
	    		BasicStroke.JOIN_BEVEL, 
	    		0, 
	    		new float[]{9}, 
	    		0);
	    g2d.setStroke(drawingStroke);
		Line2D ortaWLine = new Line2D.Double(left, height/2+30, right, height/2+30);
		Line2D topWLine = new Line2D.Double(left, top+20, right, top+20);
		Line2D bottomWLine = new Line2D.Double(left, bottom-20, right, bottom-20);
		g2d.draw(topWLine);
		g2d.draw(bottomWLine);
		if (type.equals("classification")) {
			g2d.draw(ortaWLine);
		}
		g.drawString("0.0", 10,bottom-20);
		g.drawString("0.5", 10,height/2+30);
		g.drawString("1.0", 10,top+20);
		g2d.setStroke(new BasicStroke());
		
		int tr=trainedValues.length;
		if (isOnlyPepper) {
			tr=trainedValues.length/3;
		}		
		
		if (trainedValues!=null && trainedValues.length>0) {
			int k=0;
			if (type.equals("classification")) {
				for (int i = 0; i < trainedValues.length; i++) {
					if (k%tr==0) {
						k=0;
					}
					int x=left+(int)(k*xGap);
					int y=(bottom-20)-(int)(trainedValues[i]*(height-40));
					if (desiredValues[i]==0) {
//						g.setColor(Color.orange);
//						g.fillOval(x,(bottom-20),5,5);
						if (trainedValues[i]<0.5) {
							g.setColor(Color.green);
						}else{
							g.setColor(Color.red);
						}
					}
					if (desiredValues[i]==1) {
//						g.setColor(Color.orange);
//						g.fillOval(x,(top+20),5,5);
						if (trainedValues[i]>0.5) {
							g.setColor(Color.green);
						}else{
							g.setColor(Color.red);
						}
					}
					g.drawRect(x,y,5,5);
					k++;
				}
			}else{
				int r=0;
				for (int i = 0; i < trainedValues.length; i++) {
					if (k%tr==0) {
						k=0;
					}
					int x=left+(int)(k*xGap);
					int y=(bottom-20)-(int)(trainedValues[i]*(height-40));
					int y2=(bottom-20)-(int)(desiredValues[i]*(height-40));
					g.setColor(Color.orange);
					g.fillOval(x,y2,5,5);
					if (r<pNumber) {
						g.setColor(Color.red);
					}else if(r>=pNumber && r<2*pNumber){
						g.setColor(Color.green);
					}else if(r>=2*pNumber){
						g.setColor(Color.blue);
					}
					g.drawRect(x,y,5,5);
					k++;
					r++;
				}
			}
		}
		g.setColor(Color.red);
		g.drawRect(0, 0, w-1,h-1);
    }

	private void setRelatedColor(Graphics g, int n) {
		if (desiredValues[n]==0 && trainedValues[n]<0.5) g.setColor(Color.green);
		if (desiredValues[n]==0 && trainedValues[n]>0.5) g.setColor(Color.red);
		if (desiredValues[n]==1 && trainedValues[n]>0.5) g.setColor(Color.green);
		if (desiredValues[n]==1 && trainedValues[n]<0.5) g.setColor(Color.red);
	}

	public float[] getTrainedValues() {
		return trainedValues;
	}

	public void setTrainedValues(float[] trainedValues,float[] desiredValues) {
		this.trainedValues = trainedValues;
		this.desiredValues=desiredValues;
		repaint();
	}

	public void setCurrentOutput(Vector<Float> currentOutput,Vector<Float> desiredOutput) {
		trainedValues =new float[currentOutput.size()];
		desiredValues =new float[desiredOutput.size()];
		for (int i = 0; i < currentOutput.size(); i++) {
			trainedValues[i]=Utils.formatFloat(currentOutput.get(i));
			desiredValues[i]=Utils.formatFloat(desiredOutput.get(i));
		}
		repaint();
	}

	public void setLastSelectedFeatureIndex(int value) {
		String str="qqqqqqqqqqqqqqqqqqqqqqqq";
		if (value>0) {
			str="";
		}
		for (int i = 0; i < value; i++) {
			str+=features[i]+";";
		}
		for (int z = 7; z < v.size(); z++) {
			int k=0;
			int nP=pepperNames.length/3;
			if (str.equals(v.get(z))) {
//				System.out.println(z+" str:"+str);
				for (int i = z+1; i <= z+nP; i++) {
//					System.out.println("i:"+i);
					String[] s=v.get(i).split(";");
					trainedValues[k]=Float.parseFloat(s[3]);
					trainedValues[k+nP]=Float.parseFloat(s[4]);
					trainedValues[k+2*nP]=Float.parseFloat(s[5]);
					desiredValues[k]=Float.parseFloat(s[2]);
					desiredValues[k+nP]=Float.parseFloat(s[2]);
					desiredValues[k+2*nP]=Float.parseFloat(s[2]);
					k++;
				}
				repaint();
			}
		}
	}

}  //  @jve:decl-index=0:visual-constraint="10,2"
